using System.Collections;
using UnityEngine;

[DisallowMultipleComponent]
public class EnemySpawner : SingletonMonobehaviour<EnemySpawner>
{
    private int enemiesToSpawn;
    private int currentEnemyCount;
    private int enemiesSpawnedSoFar;
    private int enemyMaxConcurrentSpawnNumber;
    private Room currentRoom;
    private RoomEnemySpawnParameters roomEnemySpawnParameters;

    private void OnEnable()
    {
        // 订阅房间更改事件
        StaticEventHandler.OnRoomChanged += StaticEventHandler_OnRoomChanged;
    }

    private void OnDisable()
    {
        // 取消订阅房间更改事件
        StaticEventHandler.OnRoomChanged -= StaticEventHandler_OnRoomChanged;
    }

    /// <summary>
    /// 处理房间变更
    /// </summary>
    private void StaticEventHandler_OnRoomChanged(RoomChangedEventArgs roomChangedEventArgs)
    {
        enemiesSpawnedSoFar = 0;
        currentEnemyCount = 0;

        currentRoom = roomChangedEventArgs.room;
        
        // 更新房间的音乐
        MusicManager.Instance.PlayMusic(currentRoom.ambientMusic, 0.2f, 2f);

        // 如果房间是走廊或入口，则返回
        if (currentRoom.roomNodeType.isCorridorEW || currentRoom.roomNodeType.isCorridorNS ||
            currentRoom.roomNodeType.isEntrance)
            return;

        // 如果房间已经被打败了，那就回来
        if (currentRoom.isClearedOfEnemies) return;

        // 获取随机数量的敌人以生成
        enemiesToSpawn = currentRoom.GetNumberOfEnemiesToSpawn(GameManager.Instance.GetCurrentDungeonLevel());

        // 获取房间敌人生成参数
        roomEnemySpawnParameters =
            currentRoom.GetRoomEnemySpawnParameters(GameManager.Instance.GetCurrentDungeonLevel());

        // 如果没有敌人生成，请返回
        if (enemiesToSpawn == 0)
        {
            // 将房间标记为已清理
            currentRoom.isClearedOfEnemies = true;

            return;
        }

        // 获取要生成的并发敌人数量
        enemyMaxConcurrentSpawnNumber = GetConcurrentEnemies();
        
        // 更新房间的音乐
        MusicManager.Instance.PlayMusic(currentRoom.battleMusic, 0.2f, 0.5f);

        // 锁门
        currentRoom.instantiatedRoom.LockDoors();

        // 生成敌人
        SpawnEnemies();
    }

    /// <summary>
    /// 生成敌人
    /// </summary>
    private void SpawnEnemies()
    {
        // 设置游戏状态为Boss阶段
        if (GameManager.Instance.gameState == GameState.bossStage)
        {
            GameManager.Instance.previousGameState = GameState.bossStage;
            GameManager.Instance.gameState = GameState.engagingBoss;
        }
        
        // 设置游戏状态，敌人阶段
        else if (GameManager.Instance.gameState == GameState.playingLevel)
        {
            GameManager.Instance.previousGameState = GameState.playingLevel;
            GameManager.Instance.gameState = GameState.engagingEnemies;
        }

        StartCoroutine(SpawnEnemiesRoutine());
    }

    /// <summary>
    /// 生成敌人协程
    /// </summary>
    private IEnumerator SpawnEnemiesRoutine()
    {
        Grid grid = currentRoom.instantiatedRoom.grid;

        //创建用于选择随机敌人的帮助程序类的实例
        RandomSpawnableObject<EnemyDetailsSO> randomEnemyHelperClass =
            new RandomSpawnableObject<EnemyDetailsSO>(currentRoom.enemiesByLevelList);

        // 检查我们是否有地方可以生成敌人
        if (currentRoom.spawnPositionArray.Length > 0)
        {
            // 循环以创建所有 enemeies
            for (int i = 0; i < enemiesToSpawn; i++)
            {
                // 等到当前敌人数量小于最大并发敌人数
                while (currentEnemyCount >= enemyMaxConcurrentSpawnNumber)
                {
                    yield return null;
                }

                Vector3Int cellPosition =
                    (Vector3Int)currentRoom.spawnPositionArray[Random.Range(0, currentRoom.spawnPositionArray.Length)];

                //创建敌人 - 获取下一个要生成的敌人类型
                CreateEnemy(randomEnemyHelperClass.GetItem(), grid.CellToWorld(cellPosition));

                yield return new WaitForSeconds(GetEnemySpawnInterval());
            }
        }
    }
    
    /// <summary>
    /// 获取最小值和最大值之间的随机生成间隔
    /// </summary>
    private float GetEnemySpawnInterval()
    {
        return (Random.Range(roomEnemySpawnParameters.minSpawnInterval, roomEnemySpawnParameters.maxSpawnInterval));
    }
    
    /// <summary>
    /// 在最小值和最大值之间获取并发敌人的随机数量
    /// </summary>
    private int GetConcurrentEnemies()
    {
        return (Random.Range(roomEnemySpawnParameters.minConcurrentEnemies, roomEnemySpawnParameters.maxConcurrentEnemies));
    }
    
    /// <summary>
    /// 在指定位置创建敌人
    /// </summary>
    private void CreateEnemy(EnemyDetailsSO enemyDetails, Vector3 position)
    {
        // 跟踪到目前为止生成的敌人数量
        enemiesSpawnedSoFar++;

        // 在当前敌人数量上增加一个 - 当敌人被摧毁时，这个数字会减少
        currentEnemyCount++;

        // 获取当前的地牢级别
        DungeonLevelSO dungeonLevel = GameManager.Instance.GetCurrentDungeonLevel();

        // 实例化敌人
        GameObject enemy = Instantiate(enemyDetails.enemyPrefab, position, Quaternion.identity, transform);

        // 初始敌人
        enemy.GetComponent<Enemy>().EnemyInitialization(enemyDetails, enemiesSpawnedSoFar, dungeonLevel);

        // 订阅敌人被摧毁事件
        enemy.GetComponent<DestroyedEvent>().OnDestroyed += Enemy_OnDestroyed;
    }
    
    /// <summary>
    /// 处理敌人被摧毁
    /// </summary>
    private void Enemy_OnDestroyed(DestroyedEvent destroyedEvent, DestroyedEventArgs destroyedEventArgs)
    {
        // 取消订阅活动
        destroyedEvent.OnDestroyed -= Enemy_OnDestroyed;

        // 减少当前敌人数量
        currentEnemyCount--;
        
        // 得分点 - 呼叫得分得分事件
        StaticEventHandler.CallPointsScoredEvent(destroyedEventArgs.points);

        if (currentEnemyCount <= 0 && enemiesSpawnedSoFar == enemiesToSpawn)
        {
            currentRoom.isClearedOfEnemies = true;

            // 设置游戏状态
            if (GameManager.Instance.gameState == GameState.engagingEnemies)
            {
                GameManager.Instance.gameState = GameState.playingLevel;
                GameManager.Instance.previousGameState = GameState.engagingEnemies;
            }

            else if (GameManager.Instance.gameState == GameState.engagingBoss)
            {
                GameManager.Instance.gameState = GameState.bossStage;
                GameManager.Instance.previousGameState = GameState.engagingBoss;
            }

            // 解锁门
            currentRoom.instantiatedRoom.UnlockDoors(Settings.doorUnlockDelay);
            
            // 更新房间的音乐
            MusicManager.Instance.PlayMusic(currentRoom.ambientMusic, 0.2f, 2f);

            // 触发房间敌人击败事件
            StaticEventHandler.CallRoomEnemiesDefeatedEvent(currentRoom);
        }
    }
}